namespace SimpleWebServices.Web.Routing
{
    using System;
    using System.Text;
    using SimpleWebServices.Globalization;

    public sealed class ResourcePath : ValueObject<ResourcePath>
    {
        public ResourcePath()
        {
            this.RegisterProperty(x => x.Extension);
            this.RegisterProperty(x => x.Language);
            this.RegisterProperty(x => x.Name);
        }

        public Extension Extension
        {
            get;
            set;
        }

        public Language Language
        {
            get;
            set;
        }

        public RouteName Name
        {
            get;
            set;
        }

        public static implicit operator ResourcePath(string value)
        {
            return (null == value) ? null as ResourcePath : ResourcePath.Parse(value);
        }

        public static implicit operator string(ResourcePath value)
        {
            return (null == value) ? null as string : value.ToString();
        }

        public static ResourcePath Parse(string path)
        {
            ResourcePath result = new ResourcePath();

            if (null != path)
            {
                if (path.StartsWith("/", StringComparison.OrdinalIgnoreCase))
                {
                    path = path.Substring(1);
                }

                if (path.EndsWith("/", StringComparison.OrdinalIgnoreCase))
                {
                    path = path.Substring(0, path.Length - 1);
                }

                if (0 != path.Length)
                {
                    string[] parts = path.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
                    if (1 == parts.Length)
                    {
                        result.Name = parts[0];
                    }
                    else
                    {
                        if (Language.IsValid(parts[parts.Length - 1]))
                        {
                            result.Language = parts[parts.Length - 1];
                        }
                        else if (Language.IsValid(parts[parts.Length - 2]))
                        {
                            result.Extension = parts[parts.Length - 1];
                            result.Language = parts[parts.Length - 2];
                        }

                        if (string.IsNullOrEmpty(result.Language))
                        {
                            result.Extension = null;
                            result.Language = null;
                        }

                        int index = parts.Length - 1;
                        index -= string.IsNullOrEmpty(result.Extension) ? 0 : 1;
                        index -= string.IsNullOrEmpty(result.Language) ? 0 : 1;
                        for (int i = index; i > -1; i--)
                        {
                            if (!string.IsNullOrEmpty(result.Name))
                            {
                                result.Name = '.' + result.Name;
                            }

                            result.Name = parts[i] + result.Name;
                        }
                    }
                }
            }

            return result;
        }

        public override string ToString()
        {
            StringBuilder buffer = new StringBuilder();
            buffer.Append(this.Name);
            if (0 != buffer.Length)
            {
                if (!string.IsNullOrEmpty(this.Language))
                {
                    buffer.Append('.');
                    buffer.Append(this.Language);
                }

                if (!string.IsNullOrEmpty(this.Extension))
                {
                    buffer.Append('.');
                    buffer.Append(this.Extension.Value);
                }
            }

            return buffer.ToString();
        }
    }
}